#include <gtest/gtest.h>
#include "Executor.hpp"
#include "PoseEq.hpp"
namespace adas
{
    //Reverse
    //CarReverse
    TEST(ExecutorReverseTest, should_return_x_minus_2_given_command_is_BM_and_facing_is_E)
    {
        //given
        std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}));
        //when
        executor->Execute("BM");
        const Pose target{-2, 0, 'E'};
        //then
        ASSERT_EQ(target, executor->Query());
    }
    TEST(ExecutorReverseTest, should_return_y_plus_1_and_facing_S_given_command_is_BL_and_facing_is_E)
    {
        //given
        std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}));
        //when
        executor->Execute("BL");
        const Pose target{0, 1, 'S'};
        //then
        ASSERT_EQ(target, executor->Query());
    }
    TEST(ExecutorReverseTest, should_return_y_minus_1_and_facing_N_given_command_is_BR_and_facing_is_E)
    {
        //given
        std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}));
        //when
        executor->Execute("BR");
        const Pose target{0, -1, 'N'};
        //then
        ASSERT_EQ(target, executor->Query());
    }
    TEST(ExecutorReverseTest, should_return_x_minus_4_given_command_is_BFM_and_facing_is_E)
    {
        //given
        std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}));
        //when
        executor->Execute("BFM");
        const Pose target{-4, 0, 'E'};
        //then
        ASSERT_EQ(target, executor->Query());
    }
    TEST(ExecutorReverseTest, should_return_x_minus_1_and_y_plus_1_and_facing_S_given_command_is_BFL_and_facing_is_E)
    {
        //given
        std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}));
        //when
        executor->Execute("BFL");
        const Pose target{-1, 1, 'S'};
        //then
        ASSERT_EQ(target, executor->Query());
    }
    TEST(ExecutorReverseTest, should_return_x_minus_1_and_y_minus_1_and_facing_N_given_command_is_BFR_and_facing_is_E)
    {
        //given
        std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}));
        //when
        executor->Execute("BFR");
        const Pose target{-1, -1, 'N'};
        //then
        ASSERT_EQ(target, executor->Query());
    }    
    TEST(ExecutorReverseTest, should_return_y_plus_2_given_command_is_BBM_and_facing_is_N)
    {
        //given
        std::unique_ptr<Executor> executor(Executor::NewExecutor());
        //when
        executor->Execute("BBM");
        const Pose target{0, 2, 'N'};
        //then
        ASSERT_EQ(target, executor->Query());
    }
    //BusReverse
    TEST(ExecutorReverseTest, should_return_x_minus_1_given_command_is_CBM_and_facing_is_E)
    {
        //given
        std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}));
        //when
        executor->Execute("CBM");
        const Pose target{-1, 0, 'E'};
        //then
        ASSERT_EQ(target, executor->Query());
    }
    TEST(ExecutorReverseTest, should_return_x_minus_1_and_facing_S_given_command_is_CBL_and_facing_is_E)
    {
        //given
        std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}));
        //when
        executor->Execute("CBL");
        const Pose target{-1, 0, 'S'};
        //then
        ASSERT_EQ(target, executor->Query());
    }
    TEST(ExecutorReverseTest, should_return_x_minus_1_and_facing_N_given_command_is_CBR_and_facing_is_E)
    {
        //given
        std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}));
        //when
        executor->Execute("CBR");
        const Pose target{-1, 0, 'N'};
        //then
        ASSERT_EQ(target, executor->Query());
    }
    TEST(ExecutorReverseTest, should_return_x_minus_2_given_command_is_CBFM_and_facing_is_E)
    {
        //given
        std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}));
        //when
        executor->Execute("CBFM");
        const Pose target{-2, 0, 'E'};
        //then
        ASSERT_EQ(target, executor->Query());
    }
    TEST(ExecutorReverseTest, should_return_x_minus_2_and_facing_S_given_command_is_CBFL_and_facing_is_E)
    {
        //given
        std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}));
        //when
        executor->Execute("CBFL");
        const Pose target{-2, 0, 'S'};
        //then
        ASSERT_EQ(target, executor->Query());
    }
    TEST(ExecutorReverseTest, should_return_x_minus_2_and_facing_N_given_command_is_CBFR_and_facing_is_E)
    {
        //given
        std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}));
        //when
        executor->Execute("CBFR");
        const Pose target{-2, 0, 'N'};
        //then
        ASSERT_EQ(target, executor->Query());
    }    
    TEST(ExecutorReverseTest, should_return_y_plus_1_given_command_is_CBBM_and_facing_is_N)
    {
        //given
        std::unique_ptr<Executor> executor(Executor::NewExecutor());
        //when
        executor->Execute("CBBM");
        const Pose target{0, 1, 'N'};
        //then
        ASSERT_EQ(target, executor->Query());
    }
}